package com.abbas.smartCity.util

import android.content.Context
import android.content.Intent
import android.widget.BaseAdapter
import android.widget.EditText
import android.widget.ImageView
import android.widget.ListView
import androidx.fragment.app.Fragment
import com.abbas.smartCity.App
import com.abbas.smartCity.R
import com.abbas.smartCity.adapter.BaseCommAdapter
import com.abbas.smartCity.bean.NetBean
import com.abbas.smartCity.okhttp.KOkGo
import com.abbas.smartCity.retroft.Api
import com.abbas.smartCity.retroft.ICallback2
import com.abbas.smartCity.retroft.RetrofitCallback2Dsl
import com.abbas.smartCity.retroft.RetrofitCallbackDsl
import com.bumptech.glide.Glide
import com.google.gson.Gson
import okhttp3.MediaType
import okhttp3.RequestBody
import org.json.JSONObject
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

/**
 * kt 扩展函数在此文件当中
 */

//ImageView使用Glide加载网络url图片或者本地图片
fun ImageView.load(src: Any?) {
    when (src) {
        null -> {
            Glide.with(this.context)
                .load(R.drawable.more_server)
                .into(this)
        }
        is String -> {
            Glide.with(this.context)
                .load(App.getBaseUrl() + src)
                .into(this)
        }
        is Int -> {
            Glide.with(this.context)
                .load( src)
                .into(this)
        }
    }
}

//EditText直接获取文本
fun EditText.text(): String = this.getText().toString()

//Map自转为一个网络访问体RequestBody
fun Map<*,*>.toRequestBody(): RequestBody = RequestBody.create(MediaType.parse("application/json"),Gson().toJson(this))

//所有类转换为 RequestBody
fun <T> T.toRequestBody(): RequestBody = RequestBody.create(MediaType.parse("application/json"),Gson().toJson(this))

//这不就是函数的强大之处吗
fun Context.startActivity(clazz: Class<*>, block: Intent.() -> Unit = {}) {
    this.startActivity(Intent(this, clazz).also(block))
}

fun Fragment.startActivity(clazz: Class<*>, block: Intent.() -> Unit = {}) {
    this.startActivity(Intent(requireContext(), clazz).also(block))
}

/**
 * mine abbas
 * now 2023-05-12 10:01
 * 不知道有没有用
 */
fun <T> ListView.setAdapterOrResetData(adapter: BaseCommAdapter<T>){
    if (this.adapter == null){
        this.adapter = adapter
    }else{
        (this.adapter as BaseCommAdapter<T>).data = adapter.data
    }
}

//OkHttp DSL// 使用Okhttp 直接以okGo开头，函数体直接调用接口访问。仅需在Activity或者Fragment当中实现 NetScope
fun NetScope.okGo(block: KOkGo.() -> Unit){
    KOkGo.also(block)
}

//Retrofit DSL// 使用retrofit直接以retrofit开头，函数体直接调用接口访问。仅需在Activity或者Fragment当中实现 NetScope
fun NetScope.retrofit(api: Api? = App.getApi(), block: Api.() -> Unit) {
    api?.apply(block)
}

//Retrofit DSL// 开始访问 此方法等同于enqueue
fun <T> Call<T>.run(dsl: RetrofitCallbackDsl<T>.() -> Unit): RetrofitCallbackDsl<T> {
    val actDsl = RetrofitCallbackDsl<T>().apply(dsl)
    enqueue(object : Callback<T> {
        override fun onResponse(call: Call<T>, response: Response<T>) {
            if (response.isSuccessful) {
                response.body()?.let {
                    /**
                     * 在此又将对象转化为json
                     * 这个损耗不应该 但是为了精准网络回调，只有这么做
                     * 替代方案依旧是下面的start方法
                     * start方法是标准化的解决方式
                     */
                    val objJson = JSONObject(App.gson.toJson(it))
                    val resultCode = objJson.optInt("code")
                    val resultMsg = objJson.optString("msg")
                    when (resultCode) {
                        in 0..199 -> {

                        }
                        in 200..299 -> {
                            actDsl.onSuccess?.invoke(it)
                        }
                        in 300..399 -> {

                        }
                        in 400..499 -> {

                        }
                        in 500..599 -> {
                            //{"code":500,"msg":"用户不存在/密码错误"}
                            actDsl.onFailure?.invoke(resultMsg)
                        }
                        else -> {
                            actDsl.onFailure?.invoke("未知错误 code:$resultCode msg:$resultMsg")
                        }
                    }
                }
            } else {
                actDsl.onFailure?.invoke("连接到服务端失败...")
            }
        }

        override fun onFailure(p0: Call<T>, p1: Throwable) {
            actDsl.onFailure?.invoke("连接到服务端出现问题... ${p1.toString()}")

        }
    })
    return actDsl
}

fun <T> Call<NetBean<T>>.start(dsl: RetrofitCallback2Dsl<T>.() -> Unit): RetrofitCallback2Dsl<T> {
    val actDsl = RetrofitCallback2Dsl<T>().apply(dsl)
    enqueue(object :ICallback2<T>(){
        override fun onSuccess(call: Call<NetBean<T>>, data: NetBean<T>) {
            actDsl.onSuccess?.invoke(data)
        }

        override fun onServerError() {
            actDsl.onNetError.invoke()
        }

        override fun onRequestError(call: Call<NetBean<T>>, msg: String) {
            actDsl.onRequestError?.invoke(msg)
        }
    })
    return actDsl
}